/********************************************************************************
	Test Functions - Group 2
********************/
#define g02fn01			1
#define g02fn02			2
#define g02fn03			3
#define g02fn04			4
#define g02fn05			5
#define g02fn06			6
#define g02fn07			7

#define g02Rastrigin	1
#define g02Sphere		2
#define g02SchafferF6	3
#define g02Rosenbrock	4
#define g02Griewangk	5
#define g02SchwefelDS	6
#define g02Ackley		7

#if test_function == 1
	#ifndef dimension
		#define dimension			30
	#endif
	#ifndef lower_bound
		#define lower_bound			-5.12
	#endif
	#ifndef upper_bound
		#define upper_bound			5.12
	#endif
	#define func_name			"Rastrigin"
	#define func				fn_rastrigin
	double func_min=0.0;
	double* min_vector;
	void build_min_vector(){
		int i;
		min_vector=(double*)malloc(sizeof(double)*dimension);
		for(i=0;i<dimension;i++)
			min_vector[i]=0.0;
	}
	double fn_rastrigin(double* x){
		int i;
		double r=10.0*dimension;
		for(i=0;i<dimension;i++){
			r+=(x[i]*x[i])-10*cos(6.2831853071795862*x[i]);
		}
		return r;
	}
#endif

#if test_function == 2
	#ifndef dimension
		#define dimension			30
	#endif
	#ifndef lower_bound
		#define lower_bound			-100.0
	#endif
	#ifndef upper_bound
		#define upper_bound			100.0
	#endif
	#define func_name			"Sphere"
	#define func				fn_sphere
	double func_min=0.0;
	double* min_vector;
	void build_min_vector(){
		int i;
		min_vector=(double*)malloc(sizeof(double)*dimension);
		for(i=0;i<dimension;i++)
			min_vector[i]=0.0;
	}
	double fn_sphere(double* x){
		int i;
		double r=0;
		for(i=0;i<dimension;i++){
			r+=x[i]*x[i];
		}
		return r;
	}
#endif

#if test_function == 3
	#define dimension			2
	#ifndef lower_bound
		#define lower_bound			-100.0
	#endif
	#ifndef upper_bound
		#define upper_bound			100.0
	#endif
	#define func				fn_schafferF6
	#define func_name			"Schaffer F6"
	double func_min=0.0;
	double* min_vector;
	void build_min_vector(){
		int i;
		min_vector=(double*)malloc(sizeof(double)*dimension);
		for(i=0;i<dimension;i++)
			min_vector[i]=0.0;
	}
	double fn_schafferF6(double* x){
		int i;
		double r=0.0;
		double t=0.0;
		t=x[0]*x[0]+x[1]*x[1];
		r=sin(sqrt(t));
		t=1+0.001*t;
		r=0.5+(r*r-0.5)/(t*t);
		return r;
	}
#endif

#if test_function == 4
	#ifndef dimension
		#define dimension			30
	#endif
	#ifndef lower_bound
		#define lower_bound			-2.048
	#endif
	#ifndef upper_bound
		#define upper_bound			2.048
	#endif
	#define func_name			"Rosenbrock"
	#define func				fn_rosenbrock
	double func_min=0.0;
	double* min_vector;
	void build_min_vector(){
		int i;
		min_vector=(double*)malloc(sizeof(double)*dimension);
		for(i=0;i<dimension;i++)
			min_vector[i]=1.0;
	}
	double fn_rosenbrock(double* x){
		int i;
		double r=0.0;
		double t1,t2;
		for(i=0;i<dimension-1;i++){
			t1=x[i+1]-x[i]*x[i];
			t2=1.0-x[i];
			r+=100*t1*t1+t2*t2;
		}
		return r;
	}
#endif

#if test_function == 5
	#ifndef dimension
		#define dimension			30
	#endif
	#ifndef lower_bound
		#define lower_bound			-600.0
	#endif
	#ifndef upper_bound
		#define upper_bound			600.0
	#endif
	#define func				fn_griewangk
	#define func_name			"Griewangk"
	double func_min=0.0;
	double* min_vector;
	void build_min_vector(){
		int i;
		min_vector=(double*)malloc(sizeof(double)*dimension);
		for(i=0;i<dimension;i++)
			min_vector[i]=0.0;
	}
	double fn_griewangk(double* x){
		int i;
		double r=0.0;
		double p=1.0;
		for (i=0;i<dimension;i++){
			r+=x[i]*x[i];
			p*=cos(x[i]/sqrt(i+1));
		}
		r=0.00025*r-p+1;
		return r;
	}
#endif

#if test_function == 6
	#ifndef dimension
		#define dimension			30
	#endif
	#ifndef lower_bound
		#define lower_bound			-100.0
	#endif
	#ifndef upper_bound
		#define upper_bound			100.0
	#endif
	#define func				fn_schwefel
	#define func_name			"Schwefel's Double Sum"
	double func_min=0.0;
	double* min_vector;
	void build_min_vector(){
		int i;
		min_vector=(double*)malloc(sizeof(double)*dimension);
		for(i=0;i<dimension;i++)
			min_vector[i]=0.0;
	}
	double fn_schwefel(double* x){
		int i,j;
		double r=0.0;
		double s=0.0;
		for (i=0;i<dimension;i++){
			s=0.0;
			for(j=0;j<=i;j++)
				s+=x[i];
			r+=s*s;
		}
		return r;
	}
#endif

#if test_function == 7
	#ifndef dimension
		#define dimension			30
	#endif
	#ifndef lower_bound
		#define lower_bound			-32.0
	#endif
	#ifndef upper_bound
		#define upper_bound			32.0
	#endif
	#define func				fn_ackley
	#define func_name			"Ackley"
	double func_min=0.0;
	double* min_vector;
	void build_min_vector(){
		int i;
		min_vector=(double*)malloc(sizeof(double)*dimension);
		for(i=0;i<dimension;i++)
			min_vector[i]=0.0;
	}
	double fn_ackley(double* x){
		int i,j;
		double r=0.0;
		double s=0.0;
		double inv=1.0/dimension;
		for (i=0;i<dimension;i++){
			s+=x[i]*x[i];
		}
		r=-20*exp(-0.2*sqrt(inv*s))+20+exp(1.0);
		s=0.0;
		for (i=0;i<dimension;i++){
			s+=cos(6.2831853071795862*x[i]);
		}
		r+=-exp(inv*s);
		return r;
	}
#endif
